﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net.Sockets;
using System.Text.RegularExpressions;
using psafth.AMB;
using psafth.FSR.Lapcounter.Sound;
using psafth.AMB.Objects;

namespace psafth.FSR.Lapcounter.UserControls
{
    public partial class SettingsUC : UserControl
    {
        private AMBListener _backgroundWorker;

        public SettingsUC()
        {
            InitializeComponent();

            tb_HostAddress.Text = Settings.IPAdress;
            tb_Port.Text = Settings.Port.ToString();
            tbSignalHornComPort.Text = Settings.SerialPort;

            _backgroundWorker = new AMBListener(Settings.IPAdress, Settings.Port);

            _backgroundWorker.WorkerReportsProgress = true;
            _backgroundWorker.WorkerSupportsCancellation = true;

            _backgroundWorker.ProgressChanged += bw_ProgressChanged;
        }

        private void SettingsUC_Load(object sender, EventArgs e)
        {

        }

        private void groupBox1_Enter(object sender, EventArgs e)
        {

        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        private void UpdateText(string text)
        {
            tbConsole.SuspendLayout();
            tbConsole.Text = tb_HostAddress.Text + text + System.Environment.NewLine;
            tbConsole.SelectionStart = tb_HostAddress.Text.Length;
            tbConsole.ScrollToCaret();
            tbConsole.ResumeLayout();
        }

        delegate void SetTextCallback(string text);

        private void SetText(string text)
        {
            this.tbConsole.Text += text;
            this.tbConsole.Select(tb_HostAddress.Text.Length, 0);
            this.tbConsole.SelectionStart = tb_HostAddress.Text.Length;
            this.tbConsole.Refresh();
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            if (_backgroundWorker.IsBusy != true)
            {
                _backgroundWorker.RunWorkerAsync();
                btnTest.Text = "Stop";
            }
            else if (_backgroundWorker.IsBusy == true)
            {
                btnTest.Text = "Test";
                _backgroundWorker.CancelAsync();
            }
        }

        //private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        //{
        //    BackgroundWorker worker = sender as BackgroundWorker;

        //    string sText = "\nStarting AMBListener...";

        //    if (tbConsole.InvokeRequired)
        //    {
        //        SetTextCallback d = new SetTextCallback(SetText);
        //        this.Invoke(d, new object[] { sText });
        //    }
        //    else
        //    {
        //        SetText(sText);
        //    }

        //    while (true)
        //    {
        //        if ((worker.CancellationPending == true))
        //        {
        //            e.Cancel = true;
        //            break;
        //        }
        //        else
        //        {
        //            try
        //            {
        //                // Create a TcpClient.
        //                // Note, for this client to work you need to have a TcpServer
        //                // connected to the same address as specified by the server, port
        //                // combination.
        //                TcpClient client = new TcpClient(Settings.IPAdress, Settings.Port);

        //                // Get a client stream for reading and writing.
        //                // Stream stream = client.GetStream();

        //                NetworkStream stream = client.GetStream();
        //                stream.ReadTimeout = 10000;
        //                stream.WriteTimeout = 10000;

        //                // Receive the TcpServer.response.
        //                while (client.Connected)
        //                {

        //                    // Buffer to store the response bytes.
        //                    Byte[] data = new Byte[256];

        //                    // String to store the response ASCII representation.
        //                    String responseData = String.Empty;

        //                    // Read the first batch of the TcpServer response bytes.
        //                    Int32 bytes = stream.Read(data, 0, data.Length);
        //                    responseData = System.Text.Encoding.UTF8.GetString(data, 1, bytes);


        //                    if (Properties.Settings.Default.Log || this.cbxSaveAsFile.Checked)
        //                        ByteArrayToFile(Application.StartupPath + "\\log.ba", data);

        //                    ReceiverObject t = new ReceiverObject(data);

        //                    if (t.MessageType == AMBMessageType.STATUS)
        //                    {
        //                        var returnobj = new StatusObject(t.Data);

        //                        sText = Environment.NewLine + "Heartbeat from " + returnobj.DecoderId;
        //                    }
        //                    else if (t.MessageType == AMBMessageType.PASSING)
        //                    {
        //                        var returnobj = new PassingObject(t.Data);

        //                        sText = Environment.NewLine + "Passing by " + returnobj.TransponderId;
        //                    }
        //                    else
        //                    {
        //                        // Simple mode.
        //                        char[] c = new char[2];

        //                        c[0] = '#';
        //                        c[1] = '@';

        //                        string[] datas = responseData.Split(c);

        //                        foreach (string s in datas)
        //                        {
        //                            string ts = string.Empty;

        //                            ts = s.Trim();
        //                            ts = ts.Replace("\n", "");

        //                            string[] datos = s.Split('\t');
        //                        }

        //                        sText = Environment.NewLine + responseData;

        //                        string[] st = new string[1];

        //                        st[0] = sText;

        //                        if (cbxSaveAsFile.Checked)
        //                            File.AppendAllLines("logtest.txt", st);
        //                    }

        //                    if (tbConsole.InvokeRequired)
        //                    {
        //                        SetTextCallback d = new SetTextCallback(SetText);
        //                        this.Invoke(d, new object[] { sText });
        //                    }
        //                    else
        //                    {
        //                        SetText(sText);
        //                    }
        //                }

        //                // Close everything.
        //                client.Close();
        //            }
        //            catch (ArgumentNullException ex)
        //            {
        //                Console.WriteLine(String.Format("ArgumentNullException: {0}", ex));
        //            }
        //            catch (SocketException ex)
        //            {
        //                // This Exception has to be active but content commented out, otherwise it will be many, many errormessages.....
        //                sText = (String.Format("SocketException: {0}", ex));

        //                if (tbConsole.InvokeRequired)
        //                {
        //                    SetTextCallback d = new SetTextCallback(SetText);
        //                    this.Invoke(d, new object[] { sText });
        //                }
        //                else
        //                {
        //                    SetText(sText);
        //                }
        //            }
        //            catch (IOException ex)
        //            {
        //                // This Exception has to be active but content commented out, otherwise it will be many, many errormessages.....
        //                Console.WriteLine(String.Format("IOException: {0}", ex));
        //            }
        //            catch (Exception ex)
        //            {
        //                Console.WriteLine(String.Format("Exception: {0}", ex));
        //            }
        //        }
        //    }
        //}

        private void ByteArrayToFile(string p, byte[] data)
        {
            File.WriteAllBytes(p, data);
        }

        private void tb_HostAddress_TextChanged(object sender, EventArgs e)
        {
            Settings.IPAdress = tb_HostAddress.Text;
        }

        private void tb_Port_TextChanged(object sender, EventArgs e)
        {
            Settings.Port = Int32.Parse(tb_Port.Text);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Player.PlaySound(0, 1000, true);
        }


        private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MainForm m = (MainForm)ParentForm;

            if ((e.Cancelled == true))
            {
                m.SetStatusLabel("User cancelled");
            }

            else if (!(e.Error == null))
            {
                m.SetStatusLabel("Error " + e.Error);
            }

            else
            {
                m.SetStatusLabel("Race finished!");
            }
        }

        private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            string sText = string.Empty;

            try
            {
                var returnObj = e.UserState as ReceiverObject;

                if (returnObj.MessageType == AMBMessageType.STATUS)
                {
                    try
                    {
                        StatusObject obj = new StatusObject(returnObj.Data);

                        sText = string.Format("Status: Inputvoltage: {0}v. Noise: {1}dB. Temperature: {2}°C", obj.InputVoltage.ToString("0.0"), obj.Noise, obj.Temperature) + Environment.NewLine;

                    }
                    catch (InvalidCastException ex)
                    {
                        MessageBox.Show(ex.Message, "Fel", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "Fel", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else if (returnObj.MessageType == AMBMessageType.PASSING)
                {
                    try
                    {
                        PassingObject obj = new PassingObject(returnObj.Data);

                        sText = string.Format("Passing: Transponderid: {0}. Signal: {1}dB. Temperature: {2}°C", obj.TransponderId, obj.SignalStrength, obj.Temperature) + Environment.NewLine;
                    }
                    catch (Exception)
                    {
                    }
                }

                if (tbConsole.InvokeRequired)
                {
                    SetTextCallback d = new SetTextCallback(SetText);
                    this.Invoke(d, new object[] { sText });
                }
                else
                {
                    SetText(sText);
                }


            }
            catch (Exception)
            {
                // TODO: Log. Then nothing.
            }
        }

        private void tbSignalHornComPort_TextChanged(object sender, EventArgs e)
        {

        }
    }
}
